package com.spzx.product.receiver;

import com.rabbitmq.client.Channel;
import com.spzx.common.rabbit.constant.MqConst;
import com.spzx.product.service.SkuStockService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @author: atguigu
 * @create: 2025-05-10 14:04
 */
@Slf4j
@Component
public class ProductReceiver {


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SkuStockService skuStockService;

    /**
     * 解锁库存库存锁定
     *
     * @param orderNo
     * @param message
     * @param channel
     */
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(MqConst.EXCHANGE_PRODUCT),
            value = @Queue(MqConst.QUEUE_UNLOCK),
            key = MqConst.ROUTING_UNLOCK
    ))
    public void unLockStock(String orderNo, Message message, Channel channel) {
        if (StringUtils.isNotBlank(orderNo)) {
            log.info("[商品服务]监听到取消库存锁定消息：{}", orderNo);
            //1.幂等性处理
            String key = "sku:unlock:" + orderNo;
            Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, orderNo, 5, TimeUnit.MINUTES);
            if (flag) {
                try {
                    //2.第一次存入,业务处理
                    skuStockService.unLockStock(orderNo);
                } catch (Exception e) {
                    redisTemplate.delete(key);//有异常直接删了可以重新投递处理
                    throw new RuntimeException(e);
                }
            }
            //3.手动ack
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }
    }


    /***
     * 监听订单支付成功后扣减订单中商品库存数量
     * @param orderNo
     * @param channel
     * @param message
     * @throws IOException
     */
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = MqConst.EXCHANGE_PRODUCT, durable = "true"),
            value = @Queue(MqConst.QUEUE_MINUS),
            key = MqConst.ROUTING_MINUS
    ))
    public void minus(String orderNo, Channel channel, Message message) {
        if (StringUtils.isNotBlank(orderNo)) {
            log.info("[订单服务]监听到订单支付成功，减库存消息：{}", orderNo);
            //1.幂等性处理
            String key = "order:minus:orderNo:" + orderNo;
            Boolean once = redisTemplate.opsForValue().setIfAbsent(key, orderNo, 5, TimeUnit.MINUTES);
            if (!once) {
                return;
            }
            try {
                //2.业务逻辑处理
                skuStockService.minusStock(orderNo);
            } catch (Exception e) {
                redisTemplate.delete(key);
                throw new RuntimeException(e);
            }
            //3.手动应答
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }
    }

}
